home *** CD-ROM | disk | FTP | other *** search
- Path: news.sprintlink.net!datalytics!usenet
- From: Rob Stewart <stew@datalytics.com>
- Newsgroups: comp.lang.c++
- Subject: Re: Another class/function pointer problem...
- Date: Fri, 05 Apr 1996 11:52:41 -0500
- Organization: Datalytics, Inc
- Message-ID: <31654FD9.1F6E@datalytics.com>
- References: <315FE1D1.E66@cs.utwente.nl>
- NNTP-Posting-Host: 204.62.224.71
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-Mailer: Mozilla 2.0 (WinNT; I)
-
- Angelo Starink wrote:
- >
- > Since I tried to use a callback function within an object, I'm
- > suffering from the class/function pointer problem as well...
- >
- > Using the "static" trick it seemed like the problem was solved
- > but now I can't get reach my class member variables:
- >
- > class Problem {
- > public:
- >
- > static CALLBACK void fn(...,...,..);
- > HWND the_window_using_this_object;
- >
- > };
- > [snip]
- > When I try to compile this, Visual C++ 2.0 says:
- > "'Problem::the_window_using_this_object' does not specify an object"
- >
-
- Your problem is that the HWND is a dm of class Problem. There
- is a separate the_window_using_this_object in each Problem
- object. A static mf has no this pointer and is not associated
- with a particular Problem instance as a result.
-
- One way to make this work is to make
- the_window_using_this_object a static dm. Then, fn can access
- it. This approach means there can be only one window associated
- with the callback at a time.
-
- class Problem
- {
- public:
- static CALLBACK void fn(...);
- private:
- static HWND m_hWindow;
- };
-
- CALLBACK void Problem::fn(...)
- {
- ::MessageBox(
- m_hWindow,
- "Whatever...",
- "Don't care",
- MB_OK);
- }
-
- The only other solution is to save the current object's this
- pointer in a static dm and then access
- the_window_using_this_object through it. This approach has the
- advantage of having an object associated with each interested
- window, and the object is associated with the callback only
- until the callback is invoked.
-
- class Problem
- {
- public:
- static CALLBACK void fn(...);
- void RegisterCallback(void);
- private:
- HWND m_hWindow;
-
- static Problem* s_pThis;
- };
-
- inline
- void Problem::RegisterCallback(void)
- {
- ASSERT(!s_pThis);
- s_pThis = this;
- }
-
- CALLBACK void Problem::fn(...)
- {
- Problem* pThis = s_pThis;
- s_pThis = 0;
- ::MessageBox(
- s_pThis->m_hWindow,
- "Whatever...",
- "Don't care",
- MB_OK);
- }
-
- Both solutions raise the spectre of multithreaded safety. As
- soon as you introduce static dms into a class, you have to
- protect access to them in a multithreaded application. You can
- protect access several ways. One way relegates all access to a
- single thread. By convention, you simply avoid accesses in any
- other thread. This is safe, provided it is well documented and
- it is easy to determine the thread from which you are accessing
- these objects.
-
- Another means to make the accesses thread safe is to protect
- them with an NT critical section, mutex, or semaphore. The
- logical thing would be to have RegisterCallback lock access to
- the static dm, and (probably) have fn release the lock. Then,
- you serialize setting and responding to the data stored in the
- static dm.
-
- --
- Robert Stewart | My opinions are usually my own.
- Datalytics, Inc. | stew@datalytics.com
-